package aliyun.cx.admin.controller;

import aliyun.cx.admin.util.ConfigUtil;
import aliyun.cx.common.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件上传控制器
 */
@RestController
@RequestMapping("/api/upload")
@CrossOrigin(origins = "*", maxAge = 3600)
public class FileUploadController {
    
    @Value("${file.upload.path}")
    private String uploadPath;
    
    @Value("${file.upload.url-prefix}")
    private String urlPrefix;
    
    private final ConfigUtil configUtil;
    
    public FileUploadController(ConfigUtil configUtil) {
        this.configUtil = configUtil;
    }
    
    /**
     * 上传图片文件（支持去重和按类型分类）
     */
    @PostMapping("/image")
    public Map<String, Object> uploadImage(
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "type", defaultValue = "general") String uploadType) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 检查文件上传是否启用
            if (!configUtil.isFileUploadEnabled()) {
                return ResponseUtil.error(403, "文件上传功能已禁用");
            }
            
            // 检查文件是否为空
            if (file.isEmpty()) {
                return ResponseUtil.error(400, "上传的文件不能为空");
            }
            
            // 检查文件类型
            String contentType = file.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                return ResponseUtil.error(400, "只能上传图片文件");
            }
            
            // 检查文件类型是否在允许列表中
            String originalFilename = file.getOriginalFilename();
            if (originalFilename != null && !configUtil.isAllowedFileType(originalFilename)) {
                String allowedTypes = configUtil.getAllowedFileTypes();
                return ResponseUtil.error(400, "不支持的文件类型，允许的类型：" + allowedTypes);
            }
            
            // 检查文件大小（使用配置中的限制）
            long maxFileSize = configUtil.getMaxFileSize();
            if (file.getSize() > maxFileSize) {
                long maxSizeMB = maxFileSize / (1024 * 1024);
                return ResponseUtil.error(400, "图片文件大小不能超过" + maxSizeMB + "MB");
            }
            
            // 计算文件MD5哈希值用于去重
            String fileHash = calculateFileHash(file);
            
            // 获取文件扩展名
            String extension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            
            // 使用MD5哈希值作为文件名（去重）
            String fileName = fileHash + extension;
            
            // 根据上传类型创建目录（替代原来的日期目录）
            String typeDir = getUploadTypeDirectory(uploadType);
            String relativePath = typeDir + "/" + fileName;
            
            // 创建完整的上传路径
            Path fullPath = Paths.get(uploadPath, typeDir);
            Files.createDirectories(fullPath);
            
            // 检查文件是否已存在
            Path filePath = fullPath.resolve(fileName);
            boolean isNewFile = !Files.exists(filePath);
            
            // 如果文件不存在，才保存
            if (isNewFile) {
                Files.copy(file.getInputStream(), filePath);
            }
            
            // 生成访问URL
            String fileUrl = urlPrefix + relativePath;
            
            // 返回结果
            Map<String, Object> data = new HashMap<>();
            data.put("fileName", fileName);
            data.put("originalName", originalFilename);
            data.put("fileSize", file.getSize());
            data.put("fileUrl", fileUrl);
            data.put("contentType", contentType);
            data.put("fileHash", fileHash);
            data.put("uploadType", uploadType);
            data.put("typeDirectory", typeDir);
            data.put("isNewFile", isNewFile);
            
            String message = isNewFile ? "图片上传成功" : "图片已存在，直接使用现有文件";
            result.put("code", 200);
            result.put("message", message);
            result.put("data", data);
            
        } catch (IOException e) {
            return ResponseUtil.error(500, "图片上传失败：" + e.getMessage());
        } catch (NoSuchAlgorithmException e) {
            return ResponseUtil.error(500, "文件哈希计算失败：" + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 根据上传类型获取目录名称
     */
    private String getUploadTypeDirectory(String uploadType) {
        switch (uploadType.toLowerCase()) {
            case "avatar":
            case "avatars":
                return "avatars"; // 用户头像
            case "cover":
            case "covers":
                return "covers"; // 文章封面、相册封面等
            case "article":
            case "articles":
                return "articles"; // 文章图片
            case "album":
            case "albums":
                return "albums"; // 相册图片
            case "photo":
            case "photos":
                return "photos"; // 照片
            case "content":
            case "contents":
                return "contents"; // 内容图片（如编辑器中的图片）
            case "system":
                return "system"; // 系统图片（如logo、背景图等）
            default:
                return "general"; // 默认/通用目录
        }
    }
    
    /**
     * 计算文件MD5哈希值
     */
    private String calculateFileHash(MultipartFile file) throws IOException, NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] hashBytes = md.digest(file.getBytes());
        
        StringBuilder sb = new StringBuilder();
        for (byte b : hashBytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
    
    /**
     * 删除图片文件
     */
    @DeleteMapping("/image")
    public Map<String, Object> deleteImage(@RequestParam("fileUrl") String fileUrl) {
        try {
            // 从URL中提取相对路径
            if (!fileUrl.startsWith(urlPrefix)) {
                return ResponseUtil.error(400, "无效的文件URL");
            }
            
            String relativePath = fileUrl.substring(urlPrefix.length());
            Path filePath = Paths.get(uploadPath, relativePath);
            
            // 检查文件是否存在
            if (!Files.exists(filePath)) {
                return ResponseUtil.error(404, "文件不存在");
            }
            
            // 删除文件
            Files.delete(filePath);
            
            return ResponseUtil.success("文件删除成功");
            
        } catch (IOException e) {
            return ResponseUtil.error(500, "文件删除失败：" + e.getMessage());
        }
    }
    
    /**
     * 检查文件是否已存在（通过URL）
     */
    @GetMapping("/image/check")
    public Map<String, Object> checkImageExists(@RequestParam("fileUrl") String fileUrl) {
        try {
            if (!fileUrl.startsWith(urlPrefix)) {
                return ResponseUtil.error(400, "无效的文件URL");
            }
            
            String relativePath = fileUrl.substring(urlPrefix.length());
            Path filePath = Paths.get(uploadPath, relativePath);
            
            boolean exists = Files.exists(filePath);
            
            Map<String, Object> data = new HashMap<>();
            data.put("exists", exists);
            data.put("fileUrl", fileUrl);
            
            return ResponseUtil.success(data);
            
        } catch (Exception e) {
            return ResponseUtil.error(500, "检查文件失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取支持的上传类型列表
     */
    @GetMapping("/types")
    public Map<String, Object> getUploadTypes() {
        Map<String, Object> data = new HashMap<>();
        Map<String, String> types = new HashMap<>();
        
        types.put("avatar", "用户头像");
        types.put("cover", "封面图片（文章、相册等）");
        types.put("article", "文章相关图片");
        types.put("album", "相册图片");
        types.put("photo", "照片图片");
        types.put("content", "内容图片（编辑器中的图片）");
        types.put("system", "系统图片（logo、背景图等）");
        types.put("general", "通用图片（默认）");
        
        data.put("types", types);
        data.put("defaultType", "general");
        
        return ResponseUtil.success("获取上传类型列表成功", data);
    }
}
